package top.codef.crypt.rsa;

import java.nio.charset.Charset;

import org.apache.commons.codec.binary.Base64;

import top.codef.crypt.CryptAlgorithm;

public class RsaUtils {

	/**
	 * 创建一个RSA密钥对，随机产生
	 * 
	 * @return
	 */
	public static RSAKeyPair createRSAKeyPair() {
		return RSAKeyPair.getInstance();
	}

	/**
	 * 创建一个密钥对，规定加密方式与验证方式
	 * 
	 * @return
	 */
	public static RSAKeyPair createRSAKeyPair(CryptAlgorithm cryptAlgorithm, SignAlgorithm signAlgorithm) {
		return RSAKeyPair.getInstance(cryptAlgorithm.getAlgorithm(), signAlgorithm.getSignType());
	}

	/**
	 * 根据公钥与私钥产生一个密钥对
	 * 
	 * @param publicKey
	 * @param privateKey
	 * @return
	 */
	public static RSAKeyPair createRSAKeyPair(String publicKey, String privateKey) {
		try {
			return new RSAKeyPair(privateKey, publicKey);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 
	 * 根据公钥与私钥产生一个密钥对
	 * 
	 * @param publicKey
	 * @param privateKey
	 * @param cryptAlgorithm
	 * @param signAlgorithm
	 * @return
	 */
	public static RSAKeyPair createRSAKeyPair(String publicKey, String privateKey, CryptAlgorithm cryptAlgorithm,
			SignAlgorithm signAlgorithm) {
		try {
			return new RSAKeyPair(privateKey, publicKey, cryptAlgorithm.getAlgorithm(), signAlgorithm.getSignType());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 公钥加密
	 * 
	 * @param keyPair
	 * @param data
	 * @return
	 */
	public static String encrypt(RSAKeyPair keyPair, String data) {
		byte[] dataByte = data.getBytes(Charset.forName("UTF-8"));
		if (dataByte.length > 245)
			throw new RSAException("数据过长");
		String encryptData = Base64.encodeBase64String(keyPair.encrypt(dataByte));
		return encryptData;
	}

	/**
	 * 公钥加密
	 * 
	 * @param publicKeyPair
	 * @param data
	 * @return
	 */
	public static String encrypt(RSAPublicKeyPair publicKeyPair, String data) {
		byte[] dataByte = data.getBytes(Charset.forName("UTF-8"));
		if (dataByte.length > 245)
			throw new RSAException("数据过长");
		String encryptData = Base64.encodeBase64String(publicKeyPair.encrypt(dataByte));
		return encryptData;
	}

	/**
	 * 
	 * 私钥加密
	 * 
	 * @param rsaKeyPair
	 * @param data
	 * @return
	 */
	public static String encryptByPrivateKey(RSAKeyPair rsaKeyPair, String data) {
		byte[] dataByte = data.getBytes(Charset.forName("UTF-8"));
		if (dataByte.length > 245)
			throw new RSAException("数据过长");
		String encryptData = Base64.encodeBase64String(rsaKeyPair.encryptByPrivateKey(dataByte));
		return encryptData;
	}

	/**
	 * 
	 * 私钥加密
	 * 
	 * @param rsaKeyPair
	 * @param data
	 * @return
	 */
	public static String encryptByPrivateKey(RSAPrivateKeyPair privateKeyPair, String data) {
		byte[] dataByte = data.getBytes(Charset.forName("UTF-8"));
		if (dataByte.length > 245)
			throw new RSAException("数据过长");
		String encryptData = Base64.encodeBase64String(privateKeyPair.encrypt(dataByte));
		return encryptData;
	}

	/**
	 * 私钥解密
	 * 
	 * @param keyPair
	 * @param data
	 * @return
	 */
	public static String decrypt(RSAKeyPair keyPair, String data) {
		byte[] dataByte = Base64.decodeBase64(data);
		byte[] decryptByte = keyPair.decypt(dataByte);
		String decryptData = new String(decryptByte, Charset.forName("UTF-8"));
		return decryptData;
	}

	/**
	 * 
	 * 私钥解密
	 * 
	 * @param privateKeyPair
	 * @param data
	 * @return
	 */
	public static String decrypt(RSAPrivateKeyPair privateKeyPair, String data) {
		byte[] dataByte = Base64.decodeBase64(data);
		byte[] decryptByte = privateKeyPair.decypt(dataByte);
		String decryptData = new String(decryptByte, Charset.forName("UTF-8"));
		return decryptData;
	}

	/**
	 * 公钥解密
	 * 
	 * @param keyPair
	 * @param data
	 * @return
	 */
	public static String decryptByPublicKey(RSAKeyPair keyPair, String data) {
		byte[] dataByte = Base64.decodeBase64(data);
		byte[] decryptByte = keyPair.decyptByPublicKey(dataByte);
		String decryptData = new String(decryptByte, Charset.forName("UTF-8"));
		return decryptData;
	}

	/**
	 * 公钥解密
	 * 
	 * @param keyPair
	 * @param data
	 * @return
	 */
	public static String decryptByPublicKey(RSAPublicKeyPair rsaPublicKeyPair, String data) {
		byte[] dataByte = Base64.decodeBase64(data);
		byte[] decryptByte = rsaPublicKeyPair.decypt(dataByte);
		String decryptData = new String(decryptByte, Charset.forName("UTF-8"));
		return decryptData;
	}

	/**
	 * 公钥加密生成签名
	 * 
	 * @param keyPair
	 * @param data
	 * @return
	 */
	public static String sign(RSAKeyPair keyPair, String data) {
		byte[] sign = keyPair.sign(data.getBytes(Charset.forName("UTF-8")));
		return Base64.encodeBase64String(sign);
	}

	/**
	 * 私钥加密生成签名
	 * 
	 * @param keyPair
	 * @param data
	 * @return
	 */
	public static String sign(RSAPrivateKeyPair rsaPrivateKeyPair, String data) {
		byte[] sign = rsaPrivateKeyPair.sign(data.getBytes(Charset.forName("UTF-8")));
		return Base64.encodeBase64String(sign);
	}

	/**
	 * 根据数据与签名验证公钥正确性
	 * 
	 * @param keyPair
	 * @param data
	 * @param sign
	 * @return
	 */
	public static boolean verify(RSAKeyPair keyPair, String data, String sign) {
		byte[] signByte = Base64.decodeBase64(sign);
		byte[] dataByte = data.getBytes(Charset.forName("UTF-8"));
		return keyPair.verifyPublicKey(dataByte, signByte);
	}

	/**
	 * 根据数据与签名验证公钥正确性
	 * 
	 * @param keyPair
	 * @param data
	 * @param sign
	 * @return
	 */
	public static boolean verify(RSAPublicKeyPair keyPair, String data, String sign) {
		byte[] signByte = Base64.decodeBase64(sign);
		byte[] dataByte = data.getBytes(Charset.forName("UTF-8"));
		return keyPair.verifyPublicKey(dataByte, signByte);
	}

}
